package com.lucifer.d.security.service.local.filter;

import com.lucifer.d.security.exception.TokenException;
import com.lucifer.d.security.model.SecurityConfigModel;
import com.lucifer.d.util.RedissonUtil;
import com.lucifer.d.util.StringUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import org.redisson.api.RedissonClient;

import java.io.IOException;
import java.util.List;

/**
 * @author Lucifer
 * @create 2024 - 07 - 15 18:34
 */
//@WebFilter(filterName = "tokenFilter",urlPatterns = "/*")
public class AuthFilter implements Filter {

    private SecurityConfigModel securityConfigModel;

    private RedissonClient redissonClient;

    private List<String> permits;

    public AuthFilter(SecurityConfigModel securityConfigModel, RedissonClient redissonClient, List<String> permits) {
        this.securityConfigModel = securityConfigModel;
        this.redissonClient = redissonClient;
        this.permits = permits;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 放行拦截
        if (permitUrl(permits, request.getRequestURI())){
            filterChain.doFilter(request,servletResponse);
        }
        // header过滤（token）
        String token = request.getHeader(securityConfigModel.getTokenHead());
        if (StringUtil.isEmpty(token)){
            // header过滤（sign）
            token = request.getHeader(securityConfigModel.getSignHead());
            if (StringUtil.isEmpty(token)){
                throw new TokenException(TokenException.CODE302);
            }
        }
        if (RedissonUtil.get(redissonClient, token) == null){
            throw new TokenException(TokenException.CODE303);
        }
        filterChain.doFilter(request,servletResponse);
    }

    private Boolean permitUrl(List<String> permits, String url){
        Boolean isPermit = false;
        for (String permit : permits){
            if (url.contains(permit)){
                isPermit = true;
                break;
            }
        }
        return isPermit;
    }

}
